import Vue from 'vue';
import { Http, ImgurlBase64 } from '../../../utils';
import { Component, Prop } from 'vue-property-decorator';
import './app-visual-upload.less';

/**
 * @description 虚拟表单文件上传
 * @export
 * @class AppVisualUpload
 * @extends {Vue}
 */
@Component({})
export class AppVisualUpload extends Vue {

  /**
   * @description 编辑器实列
   * @type {*}
   * @memberof AppVisualUpload
   */
  @Prop() editorInstance!: any;

  /**
   * @description 表单项
   * @type {*}
   * @memberof AppVisualUpload
   */
  @Prop() public parentItem!: any;

  /**
   * @description 编辑器值
   * @type {string}
   * @memberof AppVisualUpload
   */
  @Prop() public value!: string;

  /**
   * @description 编辑器名称
   * @type {string}
   * @memberof AppVisualUpload
   */
  @Prop() public name!: string;

  /**
   * @description 编辑器位置
   * @type {*}
   * @memberof AppVisualUpload
   */
  @Prop() public position!: any;

  /**
   * @description 代码表服务
   * @type {*}
   * @memberof AppVisualUpload
   */
  @Prop() public codeListService!: any;

  /**
   * @description 上下文
   * @type {string}
   * @memberof AppVisualUpload
   */
  @Prop() context!: any;

  /**
   * @description 视图参数
   * @type {string}
   * @memberof AppVisualUpload
   */
  @Prop() viewparam!: any;

  /**
   * @description 真实控件
   * @type {string}
   * @memberof AppVisualUpload
   */
  @Prop() realCompRef!: any;

  /**
   * @description http实例
   * @memberof AppVisualUpload
   */
  public http = Http.getInstance();

  /**
   * @description base64实例
   * @memberof AppVisualUpload
   */
  public base64 = ImgurlBase64.getInstance();

  /**
   * @description 文件列表
   * @type {any[]}
   * @memberof AppVisualUpload
   */
  public files: any[] = [];

  /**
   * @description 上传文件类型
   * @type {string}
   * @memberof AppVisualUpload
   */
  public uploadType: string = 'file';

  /**
   * @description 创建
   * @memberof AppVisualUpload
   */
  public created() {
    this.setFiles();
  }

  /**
   * @description 设置文件列表
   * @memberof AppVisualUpload
   */
  public setFiles() {
    if (this.value) {
      let _files = JSON.parse(this.value);
      if (Object.prototype.toString.call(_files)=='[object Array]') {
          this.files = _files;
      } else {
          this.files = [];
      }
      this.files.forEach((file: any) => {
        let url = `${this.realCompRef.downloadUrl}/${file.id}`;
        if (this.realCompRef.export_params?.length > 0) {
            url +='?';
            this.realCompRef.export_params.forEach((item:any,i:any)=>{
                url += `${Object.keys(item)[0]}=${Object.values(item)[0]}`;
                if(i<this.realCompRef.export_params.length-1){
                    url += '&';
                }
            })
        }
        file.url = url;
      });
    }
  }

  /**
   * @description 上传之前
   * @param {*} $event
   * @memberof AppVisualUpload
   */
  public async beforeFileUpload($event: any) {
    if (!this.realCompRef) {
      return
    }
    const { files } = $event.target as HTMLInputElement;
    if (files && files.length > 0) {
      if (files.length + this.files.length > this.realCompRef.limit) {
        this.realCompRef.$warning(`上传限制数量为 ${this.realCompRef.limit}`);
        return 
      }
      for (let i=0; i<files.length; i++) {
        if (!Object.is('file', this.uploadType) && files[i].type.indexOf('image/') == -1) {
          this.realCompRef.$error(`${files[i].name} 不是图片`);
          return
        }
        await this.onFileUpload(files[i]);
      }
      this.valueChange();
    }
  }

  /**
   * @description 文件上传
   * @param {*} file 文件
   * @memberof AppVisualUpload
   */
  public async onFileUpload(file: any) {
    const params = new FormData();
    params.append('file', file, file.name);
    const config = {
        headers: this.realCompRef.headers,
    }
    const response: any = await this.http.post(this.realCompRef.uploadUrl, params, config);
    if (response && response.data && response.status === 200) {
      this.onSuccess(response.data[0], file);
    } else {
      this.onError(response, file);
    }
  }

  /**
   * @description 成功
   * @param {*} response 响应
   * @param {*} file 上传文件
   */
  public onSuccess(data: any, file: any) {
    const _file = { name: data.filename, id: data.fileid };
    this.files.push(_file);
  }

  /**
   * @description 上传失败
   * @param {*} response 响应
   * @param {*} file 文件
   */
  public onError(response: any, file: any) {
    this.realCompRef.$error(`${file.name} 上传失败`);
  }

  /**
   * @description 下载
   * @param {*} file 文件
   * @memberof AppVisualUpload
   */
  public onDownload(file: any) {
    if (this.realCompRef && this.realCompRef.onDownload instanceof Function) {
      this.realCompRef.onDownload(file);
    }
  }

  /**
   * @description 删除
   * @param {*} file 文件
   * @memberof AppVisualUpload
   */
  public onDelete(file: any) {
    const index = this.files.findIndex((item: any) => Object.is(file.id, item.id));
    if (index !== -1) {
      this.files.splice(index, 1);
    }
    this.valueChange();
  }

  /**
   * @description 获取base64
   * @param {*} file 文件
   * @return {*} 
   * @memberof AppVisualUpload
   */
  public getImgURLOfBase64(file: any) {
    const config = {
      headers: this.realCompRef.headers,
    }
    this.base64.getImgURLOfBase64(file.url, config).then((response: any) => {
        this.$set(file, 'base64', response);
    });
    return file.base64;
  }

  /**
   * @description 值改变
   * @memberof AppVisualUpload
   */
  public valueChange() {
    let values: any[] = [];
    this.files.forEach((file: any) => {
      values.push({ name: file.name, id: file.id });
    });
    let value: any = values.length > 0 ? JSON.stringify(values) : null;
    this.$emit('change', { name: this.name, value: value });
  }

  /**
   * @description 绘制文件上传
   * @memberof AppVisualUpload
   */
  public renderFileUpload() {
    return (
      <div class="app-visual-file-upload">
        <div class="upload-preview-area">
          {
            this.files.map((file: any) => {
              return (
                <div class="app-file-item">
                    <a class="file-list luckysheet-mousedown-cancel" onClick={() => this.onDownload(file)}>{file.name}</a>
                    <img
                      class="app-visual-upload-icon delete luckysheet-mousedown-cancel"
                      onClick={() => this.onDelete(file)}
                      src="../assets/dist/assets/iconfont/close.svg">
                    </img>
                </div>
              )
            })
          }
        </div>
        <div class="upload-content-area">
          <button>
            文件上传
            {this.renderUpload()}
          </button>
        </div>
      </div>
    )
  }

  /**
   * @description 绘制图片上传
   * @memberof AppVisualUpload
   */
  public renderPictureUpload() {
    return (
      <div class="app-visual-picture-upload">
        {
          this.files.map((file: any) => {
            return (
              <div class="app-picture-item luckysheet-mousedown-cancel" style={{
                height: `${this.position.height - 4}px`,
                width: `${this.position.height - 4}px`,
              }}>
                <img class="app-picture-item-preview" src={this.getImgURLOfBase64(file)}></img>
                <div class="app-picture-item-action">
                  <img
                    class="app-visual-upload-icon delete luckysheet-mousedown-cancel"
                    onClick={() => this.onDelete(file)}
                    src="../assets/dist/assets/iconfont/remove.svg">
                  </img>
                  <img
                    class="app-visual-upload-icon download luckysheet-mousedown-cancel"
                    onClick={() => this.onDownload(file)}
                    src="../assets/dist/assets/iconfont/download.svg">
                  </img>
                </div>
              </div>
            )
          })
        }
        <div class="upload-content-area" 
        style={{
        height: `${this.position.height - 4}px`,
        width: `${this.position.height - 4}px`,
      }}>
          <img
            class="app-visual-upload-icon add luckysheet-mousedown-cancel"
            src="../assets/dist/assets/iconfont/add.svg">
          </img>
          {this.renderUpload()}
        </div>
      </div>
    )
  }

  /**
   * @description 绘制上传
   * @return {*} 
   * @memberof AppVisualUpload
   */
  public renderUpload() {
    return(
      <input
        type="file"
        class="upload__inner luckysheet-mousedown-cancel"
        accept={this.realCompRef.accept}
        multiple={this.realCompRef.multiple}
        disabled={this.realCompRef.disabled}
        onChange={($event: any) => {
          this.beforeFileUpload($event);
        }}>
      </input>
    )
  }

  /**
   * @description 根据类型绘制上传组件
   * @memberof AppVisualUpload
   */
  public renderUploadByType() {
    const type = this.editorInstance.editorType;
    switch (type) {
      case "FILEUPLOADER":
        this.uploadType = 'file';
        return this.renderFileUpload();
      case "PICTURE":
        this.uploadType = 'picture';
        return this.renderPictureUpload();
      default:
        this.uploadType = 'file';
        return this.renderFileUpload();
    }
  }

  /**
   * @description 绘制组件
   * @return {*}
   * @memberof AppVisualUpload
   */
  public render() {
    return (
      <div class={'app-visual-upload luckysheet-mousedown-cancel'}>
        {this.renderUploadByType()}
      </div>
    )
  }
}
